package com.zyguo.sdk.crypt;

import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.log4j.Logger;
import org.apache.log4j.LogManager;

public class AESCrypt implements ICrypt {
	private Logger logger = Logger.getLogger( this.getClass() );
	private Cipher cipher; 
	private SecretKeyFactory skFactory;
	//生成密钥需要迭代的次数，不用太多，废性能
	private static int ITERATION_COUNT = 7;
	//试过了16,64,256 都不行，只有128 不报错，不知道为什么
	private static int KEY_LENGTH = 128;
	private static byte[] salt = { 0, 7, 2, 3, 4, 5, 6, 7, 8, 1, 0xA, 0xB, 0xE, 0xD, 0xE, 0xF }; //需要转16进制

	public AESCrypt() throws Exception{
		cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
		skFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
	}
	
	//通过密码生成密钥
	private SecretKeySpec generateSecretKey(String password) throws InvalidKeySpecException {
        KeySpec spec = new PBEKeySpec( password.toCharArray(), salt, ITERATION_COUNT, KEY_LENGTH );
		try {
			SecretKey sk = skFactory.generateSecret( spec );
	        SecretKeySpec key = new SecretKeySpec( sk.getEncoded(), "AES");
	        return key;
		} catch (InvalidKeySpecException e) {
			throw e;
		}
    }
	
	@Override
	public String encrypt(String data, String password ) throws Exception {
		try {
			// 通过密码生成密钥
			SecretKeySpec secretKey = generateSecretKey( password );
			// 加密
			cipher.init( Cipher.ENCRYPT_MODE, secretKey );
			byte[] encrypt = cipher.doFinal( data.getBytes() );
			String s = new String(encrypt);
			return encrypt == null ? null : Base64.encode( encrypt );
		} catch (Exception e) {
			//logger.error("AES encrypt 异常, data=" + data + ",key=" + key, e);
			throw e;
		}
	}

	@Override
	public String decrypt(String str, String password ) throws Exception {
		try {
			byte[] data = Base64.decode( str );
			SecretKeySpec secretKey = generateSecretKey( password );
			cipher.init(Cipher.DECRYPT_MODE, secretKey); //
			byte[] result = cipher.doFinal( data );
			return new String( result ); // 解密
		} catch (Exception e) {
			//logger.error("AES decrypt 异常, data=" + data + ",key=" + key, e);
			throw e;
		}
	}
}
